package com.luxk.db.file;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import com.luxk.db.common.ImpactException;
import com.luxk.db.errorcode.ErrorCodeStorage;

public class FlatOSFile implements DBFile {
	
	private DBFileType type = DBFileType.NONE;
	private int fileId = -1;
	private String name = null;
	private String path = null;
	private long curSize = 0;
	
	private DBFileStatus status = DBFileStatus.NONE;
	
	public void init(DBFileType type, int fileId, String name, String path)
			throws ImpactException {
		this.type = type;
		this.fileId = fileId;
		this.name = name;
		this.path = path;
	}
	
	public DBFileType getType() { return this.type; }
	public int getFileId() { return this.fileId; }
	public String getName() { return this.name; }
	public String getPath() { return this.path; }
	public long getSize() { return this.curSize; }
	
	public DBFileStatus getStatus() { return this.status; }
	public void setStatus(DBFileStatus status) { this.status = status; }
		
	public void create(long size) throws ImpactException {
		File file = new File(this.path);
		
		if (file.exists())
			throw new ImpactException(ErrorCodeStorage.ERROR_CREATE_FILE,
					this.path);

		try {
			if (!file.createNewFile())
				throw new ImpactException(ErrorCodeStorage.ERROR_CREATE_FILE,
						this.path);
		} catch(IOException e) {
			throw new ImpactException(ErrorCodeStorage.ERROR_CREATE_FILE, e,
					this.path);
		}
	}
	
	public void open() throws ImpactException {
		File file = new File(this.path);
		if (!file.exists())
			throw new ImpactException(ErrorCodeStorage.ERROR_OPEN_FILE, path);
		file.length();
		this.status = DBFileStatus.OPEN;
	}
	
	public void close() throws ImpactException {
		this.status = DBFileStatus.OFFLINE;
	}
	
	public void delete() throws ImpactException {
		File file = new File(this.path);
		if (!file.exists())
			throw new ImpactException(ErrorCodeStorage.ERROR_DELETE, path);
	}
	
	public long extend(long incSize) throws ImpactException { return 0; }
	public long truncate(long remainSize) throws ImpactException { return 0; }
	
	public int read(long offset, int size, byte[] buf)
			throws ImpactException {
		RandomAccessFile file = null;
		int res = 0;
		try {
			file = new RandomAccessFile(this.path, "rwd");
			file.seek(offset);
			res = file.read(buf, 0, size);
		} catch(Exception e) {
			throw new ImpactException(ErrorCodeStorage.ERROR_READ_FILE, e,
					this.path, offset, size);
		} finally {
			try { if(file != null) file.close(); } catch(Exception e) {}
		}
		
		return res;
	}
	
	public int write(long offset, int size, byte[] buf)
			throws ImpactException {
		RandomAccessFile file = null;
		try {
			file = new RandomAccessFile(this.path, "rwd");
			file.seek(offset);
			file.write(buf, 0, size);
		} catch(Exception e) {
			throw new ImpactException(ErrorCodeStorage.ERROR_WRITE_FILE, e,
					this.path, offset, size);
		} finally {
			try { if(file != null) file.close(); } catch(Exception e) {}
		}
			
		return size;
	}
	
	public int readAioSubmit(long offset, int size, byte[] buf)
			throws ImpactException { return 0; }
	public boolean readAIOWait() throws ImpactException { return false; }
	
	public int writeAIOSubmit(long offset, int size, byte[] buf)
			throws ImpactException { return 0; }
	public boolean writeAIOWait() throws ImpactException { return false; }
}
